<template>
    <div class="news-card">
        <!-- 添加加载状态 -->
        <div v-if="loading" class="loading-overlay">
            <el-icon class="loading-icon"><Loading /></el-icon>
            <span>加载中...</span>
        </div>

        <div class="card-header">
            <h3>证券快讯</h3>
            <!-- <div class="connection-status" :class="{ connected: isConnected }"> -->
            <!-- {{ isConnected ? '已连接' : '未连接' }} -->
            <!-- </div> -->
        </div>

        <el-scrollbar height="calc(100% - 10px)" class="custom-scrollbar">
            <div class="news-list">
                <div
                    v-for="(item, index) in displayedNews"
                    :key="item.id || index"
                    class="news-item"
                    :class="{
                        'news-item-highlight': highlightedIds.has(item.id),
                    }"
                >
                    <div class="news-icon-container">
                        <div class="news-icon">
                            <el-icon>
                                <ChatLineSquare />
                            </el-icon>
                        </div>
                        <div class="news-time">
                            {{ formatTime(item.publishTime) }}
                        </div>
                    </div>
                    <div class="news-content">
                        <div class="news-title">
                            <a
                                :href="item.url"
                                target="_blank"
                                class="news-link"
                            >
                                {{ item.title }}
                            </a>
                        </div>
                    </div>
                </div>
            </div>
        </el-scrollbar>
    </div>
</template>

<script setup>
    import { ref, onMounted, onBeforeUnmount, inject } from 'vue';
    import { ChatLineSquare } from '@element-plus/icons-vue';
    import { getNews } from '@/api/api';

    // 控制暂停更新（来自父组件 Dashboard）
    const shouldPauseUpdates = inject('shouldPauseUpdates', ref(false));

    // 数据状态
    const allNews = ref([]);
    const displayedNews = ref([]);
    const isConnected = ref(false);
    const loading = ref(true); // 添加加载状态
    let ws = null;

    // 在组件级别定义重连定时器
    let reconnectTimer = null;

    // 添加初始数据获取函数
    const fetchInitialNews = async () => {
        loading.value = true; // 开始加载
        try {
            const response = await getNews();

            if (
                response &&
                response.code === '200' &&
                Array.isArray(response.data)
            ) {
                const processedData = response.data.map(item => ({
                    ...item,
                    publishTime: item.publishTime?.trim() || '',
                }));

                allNews.value = processedData;
                displayedNews.value = processedData.slice(0, 100);
                // 简化成功日志
                console.log('✅ 初始新闻数据加载成功');
            } else {
                // 保留错误日志但简化
                console.error('❌ 获取初始新闻失败');
            }
        } catch (error) {
            // 保留关键错误日志
            console.error('❌ 初始数据请求异常');
            displayMockNews();
        } finally {
            loading.value = false; // 结束加载
        }
    };

    // 添加显示模拟新闻的函数
    const displayMockNews = () => {
        const mockNews = [
            {
                id: 1,
                title: '系统维护中，稍后将恢复数据连接',
                publishTime: '08:30',
            },
            { id: 2, title: '请稍后刷新页面尝试重新连接', publishTime: '08:30' },
        ];

        allNews.value = mockNews;
        displayedNews.value = mockNews;
    };

    // 建立 WebSocket 连接
    const connectWebSocket = () => {
        const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
        const wsHost = import.meta.env.VITE_WS_HOST;

        const wsUrl = `${wsProtocol}//${wsHost}/ws/fastNews`;
        // 减少连接时的日志
        // console.log('正在连接 WebSocket:', wsUrl);

        ws = new WebSocket(wsUrl);

        ws.onopen = () => {
            console.log('✅ WebSocket连接成功');
            isConnected.value = true;
        };

        // 优化 WebSocket 消息处理函数
        ws.onmessage = event => {
            try {
                // 移除频繁的消息接收日志
                // console.log('📥 收到WebSocket消息:', event.data);
                const rawData = event.data;

                // 处理ping消息 - 移除心跳日志
                if (rawData.includes('"type":"ping"')) {
                    // console.log('收到心跳包');
                    return;
                }

                // 保留暂停更新的关键日志
                if (shouldPauseUpdates.value) {
                    // console.log('鼠标交互中，暂停数据更新');
                    return;
                }

                let data,
                    newsList = [];

                try {
                    data = JSON.parse(rawData);
                    if (
                        data &&
                        data.type === 'news' &&
                        Array.isArray(data.payload)
                    ) {
                        newsList = data.payload;
                    } else if (Array.isArray(data)) {
                        newsList = data;
                    }
                } catch (parseErr) {
                    console.error('解析数据失败:', parseErr);
                    return;
                }

                if (newsList.length === 0) return;

                // 避免代码重复检查
                if (shouldPauseUpdates.value) return;

                // 快速处理数据
                const processed = newsList.map(item => ({
                    ...item,
                    publishTime: item.publishTime?.trim() || '',
                    id: String(item.id),
                    receivedAt: Date.now(),
                }));

                // 使用Map进行高效ID查找，比Set.has()更快
                const existingIdsMap = new Map();
                allNews.value.forEach(item =>
                    existingIdsMap.set(String(item.id), true)
                );

                const newItems = processed.filter(
                    item => !existingIdsMap.has(String(item.id))
                );

                // 有新消息时立即更新UI
                if (newItems.length > 0) {
                    allNews.value = [...newItems, ...allNews.value];
                    displayedNews.value = allNews.value.slice(0, 100);
                    highlightNewItems(newItems.map(item => item.id));
                }
                // 移除重复ID的日志
                // else {
                //    console.log('❗ 收到消息但无新内容，可能是重复ID');
                // }
            } catch (err) {
                // 保留错误日志
                console.error('❌ 处理WebSocket消息失败:', err);
            }
        };

        ws.onerror = error => {
            console.error('❌ WebSocket连接出错:', error);
            isConnected.value = false;
        };

        // 改进WebSocket连接关闭和重连逻辑
        ws.onclose = () => {
            console.warn('⚠️ WebSocket连接关闭，5秒后尝试重连...');
            isConnected.value = false;

            // 清除之前的重连计时器
            if (reconnectTimer) {
                clearTimeout(reconnectTimer);
            }

            // 设置重连
            reconnectTimer = setTimeout(() => {
                // 重连前先确认之前的连接已关闭
                if (ws) {
                    try {
                        ws.close();
                    } catch (e) {
                        // 忽略可能的错误
                    }
                    ws = null;
                }
                connectWebSocket();
            }, 5000);
        };
    };

    // 时间格式化 HH:mm
    const formatTime = timestamp => {
        if (!timestamp) return '';
        if (typeof timestamp === 'string') {
            const timeMatch = timestamp.match(/\d{2}:\d{2}/);
            return timeMatch ? timeMatch[0] : '';
        }
        if (!isNaN(timestamp)) {
            const date = new Date(Number(timestamp));
            return `${date.getHours().toString().padStart(2, '0')}:${date
                .getMinutes()
                .toString()
                .padStart(2, '0')}`;
        }
        return '';
    };

    // 添加新消息高亮效果函数
    const highlightedIds = ref(new Set());

    const highlightNewItems = ids => {
        // 添加要高亮的ID
        ids.forEach(id => highlightedIds.value.add(id));

        // 3秒后移除高亮
        setTimeout(() => {
            ids.forEach(id => highlightedIds.value.delete(id));
        }, 3000);
    };

    // 生命周期：挂载时先加载初始数据，然后再连接WebSocket
    onMounted(() => {
        // 并行处理初始化
        Promise.all([
            fetchInitialNews(),
            new Promise(resolve => {
                connectWebSocket();
                // WebSocket可能需要时间连接，但不需要等待它完成
                resolve();
            }),
        ]).catch(err => {
            console.error('初始化出错:', err);
        });
    });

    // 修改组件卸载函数
    onBeforeUnmount(() => {
        if (reconnectTimer) {
            clearTimeout(reconnectTimer);
            reconnectTimer = null;
        }

        if (ws) {
            ws.close();
            ws = null;
        }
    });
</script>



<style scoped>
    @import '../assets/css/style.css';

    .news-card {
        background-color: #001e4a;
        border-radius: 5px;
        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
        height: 100%;
    }

    .custom-scrollbar {
        --el-scrollbar-bg-color: rgba(140, 214, 255, 0.2);
        --el-scrollbar-hover-bg-color: rgba(140, 214, 255, 0.5);
        padding: 15px;
    }

    :deep(.el-scrollbar__wrap) {
        overflow-x: hidden;
    }

    :deep(.el-scrollbar__bar.is-horizontal) {
        display: none;
    }

    :deep(.el-scrollbar__bar.is-vertical) {
        width: 4px;
    }

    .news-list {
        display: flex;
        flex-direction: column;
        padding-right: 5px;
    }

    .news-item {
        display: flex;
        margin-bottom: 12px;
        padding: 8px;
        background-color: #062052;
        border-radius: 4px;
    }

    .news-icon-container {
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        margin-right: 10px;
    }

    .news-icon {
        color: #8cd6ff;
        display: flex;
        align-items: flex-start;
    }

    .news-time {
        font-size: 13px;
        color: #8cd6ff;
        margin-top: 5px;
    }

    .news-content {
        flex: 1;
        text-align: left;
    }

    .news-title {
        font-size: 15px;
        line-height: 1.4;
        color: #d1d6d9;
    }

    .news-link {
        color: #d1d6d9;
        text-decoration: none;
        transition: color 0.2s;
    }

    .news-link:hover {
        color: #8cd6ff;
        text-decoration: none;
    }

    .news-link:active {
        color: #4a9ff5;
    }

    @media (min-height: 1200px) {
        .news-title {
            font-size: 16px;
        }

        .news-time {
            font-size: 14px;
        }

        .news-item {
            padding: 10px;
            margin-bottom: 15px;
        }
    }

    @media (min-height: 1800px) {
        .news-title {
            font-size: 18px;
        }

        .news-time {
            font-size: 16px;
        }

        .news-item {
            padding: 15px;
            margin-bottom: 20px;
        }
    }

    .connection-status {
        font-size: 12px;
        padding: 2px 8px;
        border-radius: 10px;
        background-color: #ff4d4f;
        color: white;
        margin-left: 10px;
    }

    .connection-status.connected {
        background-color: #52c41a;
    }

    .card-header {
        display: flex;
        align-items: center;
        padding: 10px 15px;
        border-bottom: 1px solid rgba(140, 214, 255, 0.1);
    }

    .card-header h3 {
        margin: 0;
        color: #8cd6ff;
    }

    /* 添加高亮动画效果 */
    @keyframes highlightFade {
        from {
            background-color: rgba(140, 214, 255, 0.3);
        }
        to {
            background-color: #062052;
        }
    }

    .news-item-highlight {
        animation: highlightFade 3s ease-out;
    }

    /* 添加加载状态样式 */
    .loading-overlay {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        background-color: rgba(0, 0, 0, 0.7);
        color: white;
        z-index: 10;
        border-radius: 5px;
    }

    .loading-icon {
        font-size: 24px;
        margin-bottom: 10px;
    }
</style>
